BRUTE-FORCE VECTOR GRAPHICS in BASIC and ASSEMBLY code



This is an extract from the DIY Toolkit (Qdos cardware) package. It is of interest because it 
includes BASIC and 68K assembler code to draw lines, a job which the Amiga can do in 
hardware. The complete DIY Toolkit package is available from Qdos pages like this one:

 

http://www.users.imaginet.fr/~godefroy/english/QDOS.html



The DRAW routines come in two forms. The file DRAW_ASM is the assembly code, tested 
using HiSoft's DevPac and Metacomco's assembler. You may edit and re-assemble this with 
your own assembler. DRAW_DEMO_BAS is a cut-down version in BASIC, limited to certain 
angles (see the discussion of Quadrants in the magazine) but thus even more similar to the 
Amiga hardware implementation.



The Algorithm



The algorithm to generate a straight line is simple in principle, but complicated by the need to 
draw lines in any direction at any angle. The machine code is convoluted and uses all sixteen 
68008 registers, so I wrote the algorithm in SuperBASIC for test purposes, after I wrote PLOT 
and before I machine-coded DRAW.



×DRAW_DEMO_BAS shows the algorithm in block-structured BASIC. The first stage is to find 
the direction and magnitude of the line, in the X and Y dimensions. DX indicates whether the 
line moves left (-1), right (+1) or neither left or right (0). DY is the same for vertical movement - 
in other words, DX and DY indicate the approximate direction of the line, relative to the 
horizontal and vertical.



MX and MY indicate the number of pixels to be moved vertically or horizontally. The values 
are always positive, or zero, thanks to the ABS function. Assuming pixels are square, you can 
draw a straight line at any angle between 0 and 45 degrees by stepping through a series of 
points equal to the greater of MX and MY.



At each step you advance X or Y (whichever is greater) by one. Whether you advance the 
other co-ordinate depends on the slope of the line. Since we want a straight line, the need for 
an alternate step  depends on how long it was since you last took one.

 

If MX equals MY the angle is 45 degrees and you step one pixel horizontally and vertically at 
each stage. If either DX or DY is zero, the angle is zero and you just step either horizontally or 
vertically until you get to the end. Most lines fall between these two angles. Sometimes you 
can make the step in DX and DY, but sometimes you must just step in the main direction, 
indicated by the greater of MX and MY.



The program creates two step values for each dimension; DX and DY, plus DDX and DDY for 
the alternative steps needed to cope with intermediate angles. DDX and DDY hold the 'main' 
direction. If MX exceeds MY, DDX is the same as DX, and DDY is zero. If MY is greater than 
MX, DDY matches DY and DDX is zero.



The problem is deciding when to step by (DX,DY), and when to use (DDX,DDY). The correct 
mix is determined by the ratio of MX and MY. If MX is relatively small, you must take many 
vertical steps for every horizontal one.



Since we want a continuous line, the total number of STEPS, and points to plotted, is given by 
the greater of X and Y. The number of jumps out of line, or non-contiguous PARTS, is clearly 
the lesser of X and Y.



For each step the algorithm adds the number of PARTS to a temporary variable. If the result 
exceeds the total in STEPS, the algorithm uses DX and DY to find the next point; otherwise it 
uses DDX and DDY. At the start, TEMP is set to half of the number of steps, so jumps out of 
line are evenly spaced.



Any algorithm that works for angles between 0 and 45 degrees can be persuaded to cover a 
full circle by swapping X and Y and allowing positive and negative steps. This is the role of the 
SIGN function-calls and the first IF test. The Amiga Blitter must be programmed with three bits 
to indicate the quadrant.



The Assembly code



PLOT sets a single dot in any window on the QL screen. It takes two or three integer 
parameters - an optional channel number, followed by the X and Y co-ordinates of the dot you 
want to set.



DRAW takes the same parameters - an optional channel, then the X and Y co-ordinates of the 
end of a line. It draws a straight line joining the last position used with PLOT to the dot at the 
co-ordinate supplied with DRAW. For instance this command draws a red and green striped 
line from the top left corner of the screen to the bottom right:



	WINDOW 512,256,0,0 : INK 4,2 : PLOT 0,0 : DRAW 511,255



PLOT and DRAW work in any CONsole or SCReen window; they use the current INK colour 
and recognise OVER -1 as well as OVER 0 or 1. OVER -1 combines the line colour and the 
background in such a way that re-drawing a line in the same colour restores the original 
background.



PLOT and DRAW use the 'pixel co-ordinate' scheme, explained in the 'Concepts' section of 
the QL User Guide. Co-ordinates are relative to the top left corner of the specified window, as 
for BLOCK and PIXEL%.

 

PLOT and DRAW check their parameters to ensure that they fit in  the specified or default 
window. The default channel number is #1 so you can re-direct both commands to other 
channels with USE, the March 1988 DIY Toolkit offering.\par 



The commands report 'channel not open' if the channel is closed. You get a 'bad parameter' 
error if you specify the wrong type of channel or the wrong number of parameters. 'Error in 
expression' indicates that one or more parameters could not be evaluated as integers.\par 



PLOT and DRAW return 'not complete' if called when CTRL-F5 has been pressed, to pause 
the display. You don't see this message under normal circumstances, as the operating system 
traps it, temporarily suspends the calling task, and re-tries until a key is pressed, re-enabling 
display output.



For more details and much more interesting code and commentary, see Volume G of DIY 
Toolkit, and please send me an email (simon@studio.co.uk) or a postcard if you use it!

